import datetime
import random

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import os
import re
import time
import json
import urllib
import urllib.request
import traceback
import string
from bs4 import BeautifulSoup
import jieba
import jieba.analyse

from sqlalchemy import Column, Integer, ForeignKey, String, create_engine, or_, Text, DateTime, Date, Time, text
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from PIL import ImageGrab

engine = create_engine("sqlite:///app.db", echo=True)
Base = declarative_base(bind=engine)
Session = sessionmaker(bind=engine)
session = Session()


class OrderDetail(Base):
    __tablename__ = 'order_detail'
    id = Column(Integer, primary_key=True)
    # parent_id = Column(Integer, ForeignKey('node.id'))
    xuhao = Column(String(50), comment='序号')
    orderType = Column(String(200), comment='订单类型')
    number = Column(String(500), comment='编号')
    name = Column(String(500), comment='名称')
    description = Column(Text(), comment='描述')
    company = Column(String(200), comment='客户')
    address = Column(String(500), comment='地址')
    dateFrom = Column(Date(), comment='开始')
    dateFrom_time = Column(Time(), comment='开始time')
    dateTo = Column(Date(), comment='结束')
    dateTo_time = Column(Time(), comment='结束time')
    deadline = Column(Date(), comment='截止日期')
    deadline_time = Column(Time(), comment='截止日期time')
    product = Column(String(200), comment='产品')
    defaultTechnology = Column(String(200), comment='默认工艺')
    technology = Column(String(200), comment='已选定')
    productionLine = Column(String(200), comment='生产线')
    plannedQuantity = Column(Integer, comment='计划数量')
    plannedQuantityForAdditionalUnit = Column(Integer, comment='计划数量（附加单位）')
    doneQuantity = Column(Integer, comment='完成数量')
    orderCategory = Column(String(200), comment='订单类型:无，接受订单，订单发货，订单生产中，订单结束')
    division = Column(String(200), comment='部门')
    addtime = Column(DateTime, default=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), comment='添加时间')
    # children = relationship("Node",
    #                 lazy="joined",
    #                 join_depth=10)

class Order(Base):
    __tablename__ = 'order'
    id = Column(Integer, primary_key=True)
    xuhao = Column(String(50), comment='序号')
    number = Column(String(500), comment='编号')
    name = Column(String(500), comment='名称')
    state = Column(String(200), comment='状态')
    deadline = Column(String(200), comment='截止日期')
    technologyNumber = Column(String(200), comment='工艺编号')
    productNumber = Column(String(500), comment='产品编号')
    plannedQuantity = Column(Integer, comment='计划数量')
    unit = Column(String(200), comment='单位')
    plannedQuantityForAdditionalUnit = Column(Integer, comment='附加单位计划数量')
    unitForAdditionalUnit = Column(Integer, comment='附加单位')
    companyName = Column(Integer, comment='客户')
    orderCategory = Column(String(200), comment='订单类型:无，接受订单，订单发货，订单生产中，订单结束')
    masterOrderNumber = Column(String(200), comment='主订单')
    masterOrderDefinitionNumber = Column( String( 200 ), comment = '主订单定义')
    workPlanDelivered = Column( String( 200 ), comment = '交付工作计划')
    divisionName = Column( String( 200 ), comment = '部门')
    isSubcontracted = Column( String( 200 ), comment = '分包商')
    annotation = Column( String( 200 ), comment = '批注')
    existsRepairOrders = Column( String( 200 ), comment = '修复订单')
    # 0 未写入，1 已经写入
    iswrite = Column(Integer, default = text('0'), comment = '是否写入' )
    addtime = Column(String(200), default=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), comment='添加时间')

Base.metadata.create_all()


# 读取json文件内容,返回字典格式
with open('./config.json', 'r',encoding='utf8')as fp:
    json_data = json.load(fp)
print(json_data)
# browser = webdriver.Chrome()
chrome_options = webdriver.ChromeOptions()

chrome_options.add_argument('--no-sandbox')  # 解决DevToolsActivePort文件不存在的报错
chrome_options.add_argument('window-size=1920x3000')  # 指定浏览器分辨率
chrome_options.add_argument('--disable-gpu')  # 谷歌文档提到需要加上这个属性来规避bug
chrome_options.add_argument('--hide-scrollbars')  # 隐藏滚动条, 应对一些特殊页面
chrome_options.add_argument('blink-settings=imagesEnabled=false')  # 不加载图片, 提升速度
# chrome_options.add_argument('--headless')  # 浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败
browser = webdriver.Chrome("D:\\soft\\chromedriver", chrome_options=chrome_options)
browser.maximize_window()
wait = WebDriverWait(browser, 5)




class GetData:

    def __init__(self, url=''):
        self.text_name = "read_url.txt" # 继续读取未读的URL
        self.url = url
        self.video_num = -1
        self.dir_path = "file"
        self.root_path = ""
        self.num_thread = 10  # 默认线程
        self.timeout = 10  # 超时时间设置
        self.retry = 10  # 请求网页失败的最大重试次数
        self.cover_num = -1
        self.count = 0
        self.html = ''
        self.title = ''
        self.video_success = True
        self.wrong_ts_infor = ''
        self.wrong_pic_infor = ''
        self.pic_url_list = []
        self.ts_file_list = []
        self.final_fail_ts_file_list = []
        self.list_columns = ['xuhao', 'number', 'name', 'state', 'deadline', 'technologyNumber', 'productNumber', 'plannedQuantity', 'unit','plannedQuantityForAdditionalUnit',
                       'unitForAdditionalUnit','companyName','orderCategory','orderCategory1','orderCategory2','masterOrderNumber','masterOrderDefinitionNumber',
                        'workPlanDelivered','divisionName','isSubcontracted','annotation','existsRepairOrders']

    def right_url(self):
        if re.search(r'http://demo.cloudmes.io/\w+', self.url):
            return True
        else:
            print('url不正确')

    def should_pass(self, text_name):
        # self.video_num = re.search(r'https://kzx.360kan.com/(\w+)', self.url)
        self.video_num = self.url
        # print(self.video_num)
        if not os.path.exists(text_name):
            with open(text_name, mode='w', encoding='utf-8') as ff:
                print("文件创建成功！")
            return False
        else:
            with open(text_name, 'r') as f:
                for line in f:
                    if line[:-1] == self.video_num:
                        if text_name == 'SAVED.txt':
                            print('此视频已下载，跳过\n')
                        elif text_name == 'NO EXISTS.txt':
                            print('此视频不存在，跳过\n')
                        return True
                return False

    def filter_str(self, desstr, restr=''):
        import re
        # 过滤除中英文及数字以外的其他字符
        res = re.compile("[^\u4e00-\u9fa5^a-z^A-Z^0-9]")
        return res.sub(restr, desstr)

    def download_file(self, title, ts_url):
        # print(ts_url)
        if len(title) <= 30:
            newtitle = title
        else:
            newtitle = self.filter_str(title)
            if len(newtitle) > 30:
                newtitle = newtitle[0:-29]
        try:
            urllib.request.urlretrieve(ts_url, self.dir_path + '/%s.mp4' % (newtitle))
            print('%s , %s下载成功' % (title, ts_url))
            self.write(title, url)
        except Exception as e:
            print(f"Unexpected error: {e}")

    def write(self, title, url):
        file_path = os.path.join(self.root_path, 'record.txt')
        with open(file_path, 'a', encoding='utf-8') as f:
            f.write('标题：\n%s\n网址：\n%s\n' % (title, url))

    def readurl(self):
        if os.path.exists(self.text_name):
            with open(self.text_name, 'r', encoding='utf-8') as f:
                self.url = f.read()
        return self.url

    def fenci(self, text):
        # fenci_text = jieba.cut( text )
        print('fenci')
        # print("/ ".join(fenci_text))

        # 第二步：去停用词
        # 这里是有一个文件存放要改的文章，一个文件存放停用表，然后和停用表里的词比较，一样的就删掉，最后把结果存放在一个文件中
        # stopwords = {}.fromkeys( [line.rstrip() for line in open( 'stopwords.txt' )] )
        # final = ""
        # for word in fenci_text:
        #     if word not in stopwords:
        #         if (word != "。" and word != "，"):
        #             final = final + " " + word
        # print( final )

        # 第三步：提取关键词
        a = jieba.analyse.extract_tags(text, topK=5, withWeight=True, allowPOS=())
        b = jieba.analyse.extract_tags(text, topK=6, allowPOS=())
        print(a, b)
        return b



    def newurl(self):
        browser.get(self.url)
        time.sleep(10)
        bsObj = BeautifulSoup(browser.page_source, 'html.parser')
        urls = bsObj.findAll('a', attrs={'href': re.compile("^/v\?vid")})
        try:
            newurl = '{}{}'.format(self.url.split('/v')[0], random.choice(urls).get('href'))
            with open(self.text_name, 'w', encoding='utf-8') as f:
                f.write(newurl)
        except Exception as e:
            print(f"Unexpected error: {e}")

    def download(self,user):
        url = self.readurl()
        browser.get(url)
        time.sleep(5)
        username_login = browser.find_element_by_id('usernameInput')
        password_login = browser.find_element_by_id('passwordInput')
        username_login.send_keys(user['username'])
        password_login.send_keys(user['password'])
        login_button = browser.find_element_by_id('loginButton')
        current_window_old = []
        current_window = browser.current_window_handle  # 获取当前窗口handle name
        current_window_old.append(current_window)
        login_button.click()
        # 进入下一级页面
        all_window = browser.window_handles
        for window in all_window:
            if window != current_window:
                browser.switch_to.window(window)
        current_window = browser.current_window_handle  # 获取当前窗口handle name
        current_window_old.append(current_window)
        time.sleep(10)
        # bsObj = BeautifulSoup(browser.page_source, 'html.parser')
        # 展开》计划 》生产订单
        arrow_button = browser.find_element_by_class_name('arrow')
        arrow_button.click()
        time.sleep(1)
        jihua_button = browser.find_element_by_id('firstLevelButton_orders')
        jihua_button.click()
        time.sleep(1)
        shengchan_button = browser.find_element_by_id('secondLevelButton_orders_productionOrders')
        shengchan_button.click()
        time.sleep(10)
        # 进入下一级页面
        all_window = browser.window_handles
        for window in all_window:
            if window != current_window:
                browser.switch_to.window(window)
        current_window = browser.current_window_handle  # 获取当前窗口handle name
        current_window_old.append(current_window)

        # 选中ifrem
        browser.switch_to_frame(0)
        # 选中td,然后点击td
        row = browser.find_elements_by_class_name('jqgrow')
        ids = []
        rows = []
        ordersList_url = browser.current_url

        for i in row:
            # id = i.get_attribute("id")
            ids.append(i.get_attribute("id"))
            td_text = []
            td_text.append(i.get_attribute("id"))
            for j in range(len(i.find_elements_by_tag_name('td'))):
                if j>0:
                    td_text.append(i.find_elements_by_tag_name('td')[j].text.strip())
            rows.append(dict(zip(self.list_columns,td_text)))
        print(rows)
        self.add_order(rows)
        # 写文件
        with open('./rows.json', 'w', encoding = 'utf8')as fp:
            fp.write(json.dumps(rows))

    def add_order(self, rows):
        datas = []
        for i in rows:
            res_find = session.query(Order).filter(Order.xuhao == i['xuhao']).first()
            if res_find:
                continue
            r = Order()
            r.xuhao = i['xuhao']
            r.number = i['number']
            r.name = i['name']
            r.state = i['state']
            if i['deadline']:
                r.deadline = i['deadline']
            r.technologyNumber = i['technologyNumber']
            r.productNumber = i['productNumber']
            r.plannedQuantity = i['plannedQuantity']
            r.unit = i['unit']
            r.plannedQuantityForAdditionalUnit = i['plannedQuantityForAdditionalUnit']
            r.unitForAdditionalUnit = i['unitForAdditionalUnit']
            r.companyName = i['companyName']
            r.orderCategory = "{}{}{}".format(i['orderCategory'], i['orderCategory1'], i['orderCategory2']).strip()
            r.masterOrderNumber = i['masterOrderNumber']
            r.masterOrderDefinitionNumber = i['masterOrderDefinitionNumber']
            r.workPlanDelivered = i['workPlanDelivered']
            r.divisionName = i['divisionName']
            r.isSubcontracted = i['isSubcontracted']
            r.annotation = i['annotation']
            r.existsRepairOrders = i['existsRepairOrders']
            r.addtime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            r.iswrite = 0
            # session.add(r)
            # session.commit()
            datas.append(r)
        try:
            session.add_all(datas)
            session.commit()
        except Exception as e:
            print('Error', e)
            print('traceback.print_exc():', traceback.print_exc())
            print('traceback.format_exc():', traceback.format_exc())
            raise



    # 获取详情数据，就是获取的不全
    def get_detail(self,ids,ordersList_url):
        rows = []
        for id in ids:
            browser1 = browser
            browser1.get(ordersList_url)
            js = "window.open('{}')".format(ordersList_url)
            browser1.execute_script(js)
            time.sleep(5)
            browser1.get(ordersList_url)
            browser1.switch_to_frame(0)
            time.sleep(5)
            td_button = browser1.find_element_by_id(id).find_elements_by_tag_name('td')[2]
            td_button.click()
            time.sleep(5)
            # 进入下一级页面 详情页面

            # all_window = browser1.window_handles
            # for window in all_window:
            #     if window != current_window:
            #         browser1.switch_to.window(window)
            # current_window = browser1.current_window_handle  # 获取当前窗口handle name
            # current_window_old.append(current_window)
            #bsObj = BeautifulSoup(browser1.page_source, 'html.parser')
            # orderType = browser.find_element_by_id('window.mainTab.order.gridLayout.orderType_input').text.strip()
            # mew_url = "http://demo.cloudmes.io/main.html#page/orders/orderDetails.html?context={}".format(
            #     urllib.parse.quote(str({"form.id": "{}".format(id), "form.undefined": 'null'})))
            # browser1 = browser
            # browser1.get(mew_url)
            # browser1.switch_to_frame(0)
            time.sleep(10)
            bsObj = BeautifulSoup(browser1.page_source, 'html.parser')
            r = Order()
            r.__setattr__("xuhao", id)
            r.__setattr__("orderType",browser1.find_element_by_id('window.mainTab.order.gridLayout.orderType_input').text.strip())
            number_input = browser1.find_element_by_id('window.mainTab.order.gridLayout.number_input').text.strip()
            if len(number_input) <= 0:
                number_input = browser1.find_element_by_id('window_windowHeader').text.strip()
            name_input = browser1.find_element_by_id('window.mainTab.order.gridLayout.name_input').text.strip()
            if len(name_input) <= 0:
                name_input = browser1.find_element_by_id('window_windowHeader').text.strip()
            r.__setattr__("number", number_input)
            r.__setattr__("name", name_input)
            r.__setattr__("description",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.description_input').text.strip())
            r.__setattr__("company",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.company_input').text.strip())
            r.__setattr__("address",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.address_input').text.strip())
            r.__setattr__("dateFrom",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.dateFrom_input').text.strip())
            r.__setattr__("dateFrom_time",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.dateFrom_timeInput').text.strip())
            r.__setattr__("dateTo",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.dateTo_input').text.strip())
            r.__setattr__("dateTo_time",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.dateTo_timeInput').text.strip())
            r.__setattr__("deadline",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.deadline_input').text.strip())
            r.__setattr__("deadline_time",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.deadline_timeInput').text.strip())
            r.__setattr__("product",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.product_input').text.strip())
            r.__setattr__("defaultTechnology",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.predefinedTechnology.predefinedTechnologyGridLayout.defaultTechnology_input').text.strip())
            r.__setattr__("technology",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.predefinedTechnology.predefinedTechnologyGridLayout.technology_input').text.strip())
            r.__setattr__("productionLine",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.productionLine_input').text.strip())
            r.__setattr__("plannedQuantity",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.basicUnitGrid.plannedQuantity_input').text.strip())
            r.__setattr__("plannedQuantityForAdditionalUnit",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.additionalUnitGrid.plannedQuantityForAdditionalUnit_input').text.strip())
            r.__setattr__("doneQuantity",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.doneQuantityGrid.doneQuantity_input').text.strip())
            r.__setattr__("orderCategory",
                          browser1.find_element_by_id('window.mainTab.order.gridLayout.orderCategory_input').text.strip())
            r.__setattr__("division",
                          browser1.find_element_by_id(
                              'window.mainTab.order.gridLayout.division_input').text.strip())
            rows.append(r)
            try:
                browser1.get_screenshot_as_file("../img/{}_{}.png".format('ordersList_url',id))
            except IOError as e:
                print(e)
            browser1.close()
            time.sleep(10)
            # 切换回原标签
            all_window = browser.window_handles
            browser.switch_to.window(all_window[0])
        print(rows)
        # browser.quit()



        # src = bsObj.find('div', id='mse').find("video")["src"]
        # # print(text)
        # title = bsObj.find('h1', class_='videoinfo-title').text.replace('万次播放', '')
        # if len(title.split("：")) > 1:
        #     title = title.split("：")[1]
        # try:
        #     views = bsObj.find('div', class_='videoinfo-playnums').text.split("|")[0].replace('万次播放', '')
        #     print(title, views, src)
        #     parent = session.query(Node).filter(or_(Node.title == title, Node.src == src)).first()
        #     if parent is None:
        #         node = Node(title=title, src=src, views=views)
        #         session.add(node)
        #         session.commit()
        #     self.newurl()
        # except:
        #     print("文件{}错误".format(src))
        #     print('traceback.print_exc():', traceback.print_exc())
        #     print('traceback.format_exc():', traceback.format_exc())


if __name__ == '__main__':
    # url = input('请输入网址：\n')
    count = 1000
    start = time.perf_counter()
    url = json_data[0]['cloudmes']['url']
    users = json_data[0]['cloudmes']['users']
    i = users[0]
    # for i in users:
        # one = session.query( Node ).order_by(Node.id.desc()).first()
    Get_Data = GetData(url)
    Get_Data.download(i)
    time.sleep(10)
    end = time.perf_counter()
    print('任务执行共%d小时%d分%.2f秒,' % ((end - start) // 3600, (end - start) % 3600 // 60, (end - start) % 60))
    browser.quit()


